package org.lboot.idmo.controller;

import cn.dev33.satoken.stp.StpUtil;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.bean.copier.CopyOptions;
import cn.hutool.core.lang.Validator;
import cn.hutool.core.lang.tree.Tree;
import cn.hutool.core.lang.tree.TreeNodeConfig;
import cn.hutool.core.lang.tree.TreeUtil;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.lboot.core.auth.AuthService;
import org.lboot.core.domain.ResponseDTO;
import org.lboot.idmo.module.role.SysRole;
import org.lboot.idmo.module.rsr.AuthRsr;
import org.lboot.idmo.module.rsr.AuthRsrService;
import org.lboot.idmo.module.rsr.params.RsrCreateParams;
import org.lboot.idmo.module.rsr.params.RsrUpdateParams;
import org.lboot.idmo.module.user.role.SysUserRole;
import org.lboot.idmo.module.user.role.SysUserRoleService;
import org.springframework.http.HttpStatus;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

@Slf4j
@RestController
@RequestMapping("idm")
@AllArgsConstructor
@Api(tags = "资源管理")
public class IdmoRsrController {
    AuthRsrService rsrService;

    SysUserRoleService userRoleService;

    @PostMapping("rsr")
    @ApiOperation(value = "资源新建")
    public ResponseDTO<Object> rsrCreate(@Validated @RequestBody RsrCreateParams params){
        AuthRsr rsr = new AuthRsr();
        BeanUtil.copyProperties(params, rsr, CopyOptions.create().setIgnoreNullValue(true).setIgnoreError(true));
        if (Validator.isEmpty(rsr.getParentId())){
            rsr.setParentId(0L);
        }
        // 不允许重复路由
        return ResponseDTO.succData(
                rsrService.saveOne(rsr)
        );
    }

//    @PutMapping("rsr")
//    @ApiOperation(value = "资源更新")
//    public ResponseDTO<Object> rsrUpdate(@Validated @RequestBody RsrUpdateParams params){
//        AuthRsr rsr = rsrService.getOneUnwrap(params.getId());
//        BeanUtil.copyProperties(params, rsr, CopyOptions.create().setIgnoreError(true).setIgnoreNullValue(true));
//        return ResponseDTO.succData(
//                rsrService.updateOne(rsr)
//        );
//    }

    @PutMapping("rsr/{id}")
    @ApiOperation(value = "资源更新(路径参数)")
    public ResponseDTO<Object> rsrUpdate(@PathVariable("id") Long id,@Validated @RequestBody RsrUpdateParams params){
        AuthRsr rsr = rsrService.getOneUnwrap(id);
        BeanUtil.copyProperties(params, rsr, CopyOptions.create().setIgnoreError(true).setIgnoreNullValue(true));
        return ResponseDTO.succData(
                rsrService.updateOne(rsr)
        );
    }

    @DeleteMapping("rsr/{id}")
    @ApiOperation(value = "资源删除")
    public ResponseDTO<Object> rsrDelete(@PathVariable("id") Long id){
        rsrService.deleteOne(id);
        return ResponseDTO.succMsg("删除成功");
    }

    @GetMapping("rsr")
    @ApiOperation(value = "资源列表")
    public ResponseDTO<Object> rsrListQuery(){
        return ResponseDTO.succData(
                rsrService.getAll()
        );
    }


    @GetMapping("rsr/tree")
    @ApiOperation(value = "资源树")
    public ResponseDTO<Object> rsrTree(){
        // 获取当前登录用户信息
        Long loginId = StpUtil.getLoginIdAsLong();
        // 获取用户权限列表
        List<SysRole> roles = userRoleService.getRoles(loginId);
        // 提取权限列表
        List<Long> permissions = new ArrayList<>();
        for (SysRole role:roles){
            permissions.addAll(role.getPermissions().stream()
                    .map(Long::parseLong)
                    .collect(Collectors.toList()));
        }
        List<AuthRsr> rsrs = rsrService.getByType("MENU");
        // 如果不是 admin 需要筛选
        if (!StpUtil.hasRole("admin")){
            rsrs = rsrs.stream().filter(ele-> permissions.contains(ele.getId())).collect(Collectors.toList());
        }
        //配置
        TreeNodeConfig treeNodeConfig = new TreeNodeConfig();
        treeNodeConfig.setWeightKey("order");
        treeNodeConfig.setIdKey("id");
        // 最大递归深度
        treeNodeConfig.setDeep(4);
        List<Tree<String>> treeNodes = TreeUtil.build(rsrs, "0", treeNodeConfig,
                (treeNode, tree) -> {
                    tree.setId(treeNode.getId().toString());
                    if (Validator.isNotEmpty(treeNode.getParentId())){
                        tree.setParentId(treeNode.getParentId().toString());
                    }else {
                        tree.setParentId("0");
                    }
                    tree.setWeight(treeNode.getOrderNum());
                    tree.setName(treeNode.getName());
                    tree.putExtra("code",treeNode.getCode());
                    tree.putExtra("icon",treeNode.getIcon());
                    tree.putExtra("type", treeNode.getType());
                    tree.putExtra("path", treeNode.getPath());
                    tree.putExtra("component", treeNode.getComponent());
                    tree.putExtra("layout", treeNode.getLayout());
                    tree.putExtra("show", treeNode.getShow());
                    tree.putExtra("enable", treeNode.getEnable());
                    tree.putExtra("keepAlive", treeNode.getKeepAlive());
                    tree.putExtra("order", treeNode.getOrderNum());
                    tree.putExtra("orderNum", treeNode.getOrderNum());
                    tree.putExtra("description", treeNode.getDescription());
                });
        return ResponseDTO.succData(treeNodes);
    }

    @GetMapping("rsr/{id}")
    @ApiOperation(value = "资源查询")
    public ResponseDTO<Object> rsrQuery(@PathVariable("id") Long id){
        return ResponseDTO.succData(
                rsrService.getOneUnwrap(id)
        );
    }

    @GetMapping("rsr/{id}/children")
    @ApiOperation(value = "子资源查询")
    public ResponseDTO<Object> rsrChildrenQuery(@PathVariable("id") Long id, @RequestParam("type") String type){
        if (Validator.isEmpty(type)){
            List<AuthRsr> rsrs = rsrService.getByParentId(id);
            return ResponseDTO.succData(
                    rsrs
            );
        }else {
            if (type.equals("BUTTON") || type.equals("MENU")){
                List<AuthRsr> rsrs = rsrService.getByParentIdAndType(id, type);
                return ResponseDTO.succData(rsrs);
            }else {
                return ResponseDTO.wrap(HttpStatus.BAD_REQUEST,"类型错误");
            }
        }
    }
}
